#!/usr/bin/env python
import urllib2, urllib, json, time, pickle
from itertools import *
from operator import itemgetter

"""
What do i need from this file?
    - plotting data
        - percentage of probes reaching 
    - probe IDs of detected debogons for scheduling traceroutes
    - stats
        - how many ASNs
        - what country coverage
        - 
    
TODO:
*****ARE the sets ordered with regards to time?
"""

"""
1. Results dropped from the dataset:
    A. Such, that:
         - ICMP unreachable for the duration of the entire test towards both the bogon and the reference
         - probes that shut down during the testing
            - such results should still be considered, if they've returned something. Namely, in case, there exists successful ping to either the bogon or the reference part of the same hour:
                a. UNSUCCESSFUL
                    - 
    B. Intermittent results - in case a ping to the debogon succeeded in an hour, or 
       the control point, it remains in the dataset
""" 
"""

"""
with open("185.1.0.0_21/185.1.1.1", 'rb') as f:
    bogonPing = pickle.load(f)
with open("185.1.0.0_21/84.205.83.1", 'rb') as f:
    referencePing = pickle.load(f)
#Filter results from probs that can't reach (ICMP unreachable) both the bogon and the reference for the entire duration
#-------------------------------------------------------------------------------------------------------------------------
#First from the referene pings get all probe IDs, from which the target was unreachable for the duration of the entire test
probeIDs1 = list()
for prb_id, pingData in referencePing.items():
    #Get all keys associated with values containing 3 starts (in the result section) for the duration of all pings
    unreachable = 0
    for pingResult in pingData:
        if str(pingResult.get("result")).count("*") == 3:
            unreachable +=1
    if unreachable == len(pingData):
        probeIDs1.append(prb_id)
        unreachable = 0
    else:
        unreachable = 0
#print sorted(probeIDs1)

#Next, from the bogon pings, check the pings results of all previously collected probe IDs
probeIDs2 = list()
for prb_id in probeIDs1:
    #Count unreachable ping results in corresponding reference set
    unreachable = 0
    for pingData in bogonPing.get(prb_id):
        if str(pingData.get("result")).count("*") == 3:
            unreachable +=1
    if unreachable == len(bogonPing.get(prb_id)):
        probeIDs2.append(prb_id)
    unreachable = 0

#print sorted(probeIDs2)
#print sorted(list(set(probeIDs1).intersection(probeIDs2)))
#Remove measurements for probes that could not reach either target for the entire duration
for i in list(set(probeIDs1).intersection(probeIDs2)):
    bogonPing.pop(i, None)
    referencePing.pop(i, None)
#-------------------------------------------------------------------------------------------------------------------------

#Order values in both sets by timestamp
#-------------------------------------------------------------------------------------------------------------------------
for k,v in bogonPing.items():
    sortedList = sorted(v, key=itemgetter('timestamp')) 
    bogonPing[k] = sortedList
for k,v in referencePing.items():
    sortedList = sorted(v, key=itemgetter('timestamp')) 
    referencePing[k] = sortedList
#-------------------------------------------------------------------------------------------------------------------------
    
#Get all cases in which reference was pingable but bogon wasnt
#-------------------------------------------------------------------------------------------------------------------------
bogonProbe = list()
for prb_id, pingData in bogonPing.items():
    #Get all keys associated with values containing 3 starts (in the result section) for the duration of all pings
    unreachable = 0
    for pingResult in pingData:
        if str(pingResult.get("result")).count("*") == 3:
            unreachable +=1
    if unreachable == len(pingData):
        bogonProbe.append(prb_id)
    unreachable = 0

print bogonProbe
#-------------------------------------------------------------------------------------------------------------------------

#Create plot dataset, such that output is two columns: (NumberOfProbesReaching,Time)
#-------------------------------------------------------------------------------------------------------------------------
#First put all pings within the same timeslices (normalize), by getting first timestamp and modifying all others to be a subsum of it
startTimestamp = 1390995900
endTimestamp = 1391039460
for pings in bogonPing.values():
    step = 0
    #Iterate over all ping results and change the
    for j in pings:
        j["startTimestamp"] = startTimestamp +(step*1320)
    step +=1


#Next, iterave over each timeslice and get active probes within it(at least one ICMP reply received)
sliceCounter = 0
slices = dict() #11 in total
for time in range(1390995900, 1391039460, 1320):
    #Iterate over each probe for each timeslice
    for prb_id, result in bogonPing.items():
        #Iterate over probe results and capture those withime upper and lower timeslice to the new dict in case there is a ping whose packet was anwered
        for ping in result:
            if ping.get("timestamp") >= time and ping.get("timestamp") <=time+1320 and str(ping.get("result")).count("*") < 3:
                if sliceCounter in slices.keys():
                    slices[sliceCounter].append(prb_id)
                else:   
                    slices[sliceCounter] = [prb_id]
    sliceCounter +=1


#Finally output data to a file
counter = 0
for sliceID, probeIDs in slices.items():
    with open("185.1.1.1_plot.data", 'a') as f:
        f.write(str(startTimestamp+(counter*1320))+"    "+str(len(set(probeIDs)))+"\n")
        
"""

#slices = {sliceID:{prb_ID:[{pingData1}, {pingData1}]}}
slices = dict() #11 in total
sliceCounter = 0
#Next get the number of probes that could reach target on an 30 min basis
for prb_id, result in bogonPing.items():
    #Iterate thru all pings in a 30 min slice
    for ping in result:
        if ping.get("startTimestamp") <= startTimestamp+1800 and ping.get("startTimestamp") >= startTimestamp-1800 and str(ping.get("result")).count("*") < 3:
            if sliceCounter in slices.keys():
                slices[sliceCounter].extend(prb_id)
            else:   
                slices[sliceCounter] = [prb_id]
    sliceCounter +=1
    startTimestamp +=1800
    #Check if there has been a reachable one
        #Save probeID under given sliceID


for k,v in slices.items():
    print k,v
"""
#-------------------------------------------------------------------------------------------------------------------------


